﻿/*******************************************************************************
 * Copyright (c) 2007
 * Sergey Berezin, Dmitry Voitsekhovskiy
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms,
 * with or without modification, are permitted provided
 * that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * - Neither the name of the Moscow State University nor the names
 * of its contributors may be used to endorse or promote products
 * derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ******************************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Faml
{
    public static class IndicesUtils
    {
        /// <summary>
        /// Describes an array of indices
        /// </summary>
        /// <param name="indices">Indices array</param>
        /// <param name="min">Minimal index (or -1)</param>
        /// <param name="max">Maximal index (or -1)</param>
        /// <param name="step">Step (if array is regular, otherwise -1)</param>
        /// <param name="ordered">True if it is ordered (STRICTLY ascendancy)</param>
        public static void Describe(int[] indices, out int min, out int max, out int step, out bool ordered)
        {
            if (indices.Length == 0)
            {
                min = max = step = -1;
                ordered = true;
                return;
            }

            if (indices.Length == 1)
            {
                min = max = indices[0];
                step = 1;
                ordered = true;
                return;
            }

            step = indices[1] - indices[0];
            min = indices[0];
            max = indices[indices.Length - 1];
            ordered = true;
            if(max < min)
            {
                max = min; ordered = false;
            }

            int dx;
            for (int i = 1; i < indices.Length; i++)
            {
                if (min > indices[i])
                {
                    ordered = false;
                    min = indices[i];
                }
                else if (max < indices[i])
                {
                    ordered = false;
                    max = indices[i];
                }

                dx = indices[i] - indices[i - 1];
                if(ordered && dx <= 0)
                    ordered = false;

                if (ordered && step > 0 && (step != dx))
                {
                    step = -1;
                }
            }

            if (!ordered)
                step = -1;
        }
    }
}
